package com.hzjh.base.utils.function

import android.os.Handler
import android.os.Looper
import android.view.View
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.lifecycleScope
import com.blankj.utilcode.util.ScreenUtils
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.onCompletion
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.launch

//当前时间
fun nowTime() = System.currentTimeMillis()
//分辨率高度，包含状态栏和导航栏
val screenHeight: Int get() = ScreenUtils.getScreenHeight()
//分辨率宽度
val screenWidth: Int get() = ScreenUtils.getScreenWidth()

/** json相关 **/
fun Any.toJson() = Gson().toJson(this)

//内联函数+标注泛型 = 泛型实例化
inline fun <reified T> String.toBean() = Gson().fromJson<T>(this, object : TypeToken<T>() {}.type)

/**
 * 显示或隐藏，
 * @param visibleDo 只会在显示执行
 */
inline fun <T : View> T.visibleOrGone(
    visible: Boolean,
    goneMode: Int = View.GONE,
    crossinline visibleDo: (T.() -> Unit)
) {
    visibility = if (visible) {
        visibleDo.invoke(this)
        View.VISIBLE
    } else goneMode
}

inline fun <T : View> T.visibleOrGone(visible: Boolean) {
    visibility = if (visible) {
        View.VISIBLE
    } else View.GONE
}

fun <T : View> T.visibleOrInVisible(visible: Boolean) {
    visibility = if (visible) {
        View.VISIBLE
    } else View.INVISIBLE
}

/**
 * 主线程运行
 */
fun Any.runOnUIThread(block: () -> Unit) {
    Handler(Looper.getMainLooper()).post { block() }
}

/**
 * 倒计时的实现
 */
@ExperimentalCoroutinesApi
fun FragmentActivity.countDown(
    time: Int = 5,
    start: (scop: CoroutineScope) -> Unit,
    end: () -> Unit,
    next: (time: Int) -> Unit
) {

    lifecycleScope.launch {

        // 在这个范围内启动的协程会在Lifecycle被销毁的时候自动取消

        flow {
            (time downTo 0).forEach {
                delay(1000)
                emit(it)
            }
        }.onStart {
            // 倒计时开始 ，在这里可以让Button 禁止点击状态
            start(this@launch)

        }.onCompletion {
            // 倒计时结束 ，在这里可以让Button 恢复点击状态
            end()

        }.catch {
            //错误

        }.collect {
            // 在这里 更新值来显示到UI
            next(it)
        }

    }
}